#pragma once
#include <queue>
#include <mutex>
#include <condition_variable>
#include <iostream>


namespace WD {
template<typename T>
class ThreadSafeQueue {
public:
    void push(const T& val) {
        std::lock_guard<std::mutex> lock(mtx_);
        q_.push(val);
        cv_.notify_one();
    }

    bool pop(T& val, std::atomic<bool>& running) {
        std::unique_lock<std::mutex> lock(mtx_);
        // std::cout << "Waiting for item or shutdown...\n";
        cv_.wait(lock, [&] { return !q_.empty() || !running.load(); });

        if (q_.empty()) {
            std::cout << "Queue empty and running == false, exiting pop()\n";
            return false;
        }

        val = q_.front();
        q_.pop();
        return true;
    }


    void clear() {
        std::lock_guard<std::mutex> lock(mtx_);
        // 清空队列
        std::queue<T> empty;
        std::swap(q_, empty);
    }

    void notifyAll() {
        cv_.notify_all();
    }


    bool try_pop(T& val) {
        std::lock_guard<std::mutex> lock(mtx_);
        if (q_.empty()) return false;
        val = q_.front();
        q_.pop();
        return true;
    }

private:
    std::queue<T> q_;
    std::mutex mtx_;
    std::condition_variable cv_;
};
} // namespace WD
